package com.yuantu.judiciary.serviceimpl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yuantu.judiciary.common.CodeEnum;
import com.yuantu.judiciary.dao.IAccountDao;
import com.yuantu.judiciary.dao.IOrganizationDao;
import com.yuantu.judiciary.dao.ISearchRecordDao;
import com.yuantu.judiciary.exception.enums.AccountExceptionEnum;
import com.yuantu.judiciary.exception.enums.OrganizationExceptionEnum;
import com.yuantu.judiciary.model.domain.AccountDO;
import com.yuantu.judiciary.model.domain.OrganizationDO;
import com.yuantu.judiciary.model.domain.SearchRecordDO;
import com.yuantu.judiciary.model.dto.SearchRecordContentDTO;
import com.yuantu.judiciary.model.enums.AccountState;
import com.yuantu.judiciary.model.enums.AuthState;
import com.yuantu.judiciary.model.enums.SearchType;
import com.yuantu.judiciary.model.form.AddSearchRecordForm;
import com.yuantu.judiciary.model.vo.SearchRecordVO;
import com.yuantu.judiciary.service.ISearchRecordService;
import com.yuantu.judiciary.utils.AssertUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 搜索记录接口实现
 *
 * @author syw
 * @since 2023-07-07
 **/
@Service
@RequiredArgsConstructor
public class SearchRecordServiceImpl implements ISearchRecordService {

    private final ISearchRecordDao searchRecordDao;
    private final IAccountDao accountDao;
    private final IOrganizationDao organizationDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(Long userId, AddSearchRecordForm form) {
        SearchRecordDO searchRecord = searchRecordDao.findFirstByCreatorIdAndTypeAndContentAndDeletedFalse(
                userId, form.getType(), JSON.toJSONString(form.getContent())
        );
        if (ObjectUtils.isEmpty(searchRecord)) {
            searchRecord = new SearchRecordDO();
            searchRecord.setCreatorId(userId);
            searchRecord.setContent(JSON.toJSONString(form.getContent()));
            searchRecord.setType(form.getType());
        } else {
            Timestamp currentTime = new Timestamp(System.currentTimeMillis());
            searchRecord.setCreateTime(currentTime);
            searchRecord.setModifyTime(currentTime);
        }
        return searchRecordDao.save(searchRecord).getId() > 0;
    }

    @Override
    public List<SearchRecordContentDTO> listLimit(Long userId, SearchType type) {
        return searchRecordDao.findFirst10ByCreatorIdAndTypeAndDeletedFalseOrderByCreateTimeDesc(userId, type).stream().map(
                data -> JSON.parseObject(data.getContent(), SearchRecordContentDTO.class)
        ).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteAll(Long userId, SearchType type) {
        searchRecordDao.deleteByCreatorIdAndType(userId, type, new Timestamp(System.currentTimeMillis()));
        return true;
    }

    @Override
    public String verify(Long accountId, AddSearchRecordForm form) {
        AccountDO account = this.accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), (CodeEnum) AccountExceptionEnum.ACCOUNT_NOT_EXIST);

        OrganizationDO organization = this.organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), (CodeEnum) OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);

        if(form.getType().equals(SearchType.PERSON)){
            if(!AuthState.PASS.equals(organization.getAuthState()))
                return AccountState.AUTH_NOT_PASS.name();
        }
        return AccountState.NORMAL.name();
    }

    @Override
    public List<SearchRecordContentDTO> hotSearch() {
        return searchRecordDao.findTop10().stream().map(
                data -> JSON.parseObject(data.get("content").toString(), SearchRecordContentDTO.class)
        ).collect(Collectors.toList());
    }
}
